package team.first.movieapiv2pro.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import team.first.movieapiv2pro.controller.MovieController;
import team.first.movieapiv2pro.dao.MovieDAO;
import team.first.movieapiv2pro.domain.Movie;
import team.first.movieapiv2pro.dto.RequestMovie;
import team.first.movieapiv2pro.service.MovieService;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Author: HAPPY
 * @Project_name: project
 * @Package_name: team.first.movieapiv2pro.service.impl
 * @Date: 2021/12/26 10:33
 * @Description:
 */
@Service
public class MovieServiceImpl implements MovieService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private MovieDAO movieDAO;

    @Override
    public Movie getById(Integer movieId) {
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String movieCache = operations.get("movie-api-v2:data:movie:" + movieId);
        Movie movie = null;
        if (movieCache != null) {
            movie = JSON.parseObject(movieCache, Movie.class);
        } else {
            movie = movieDAO.selectById(movieId);
            // 做缓存, 10分钟
            operations.set("movie-api-v2:data:movie:" + movieId, JSON.toJSONString(movie), Duration.ofSeconds(60 * 10));
        }
        return movie;
    }

    @Override
    public List<Movie> getMovie(RequestMovie movie) {
        // 建立查询条件
        BasicDBObject filter_dbobject = new BasicDBObject();
        if (movie.getOriginalTitle() != null) {
            filter_dbobject.put("originalTitle", Pattern.compile("^.*" + movie.getOriginalTitle() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (movie.getChineseTitle() != null) {
            filter_dbobject.put("chineseTitle", Pattern.compile("^.*" + movie.getChineseTitle() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        List<BasicDBObject> yearConditions = new ArrayList<>();
        if (movie.getStartYear() != null) {
            BasicDBObject basicDBObject = new BasicDBObject();
            basicDBObject.append("year", new BasicDBObject("$gte", movie.getStartYear()));
            yearConditions.add(basicDBObject);
        }
        if (movie.getEndYear() != null) {
            BasicDBObject basicDBObject = new BasicDBObject();
            filter_dbobject.append("year", new BasicDBObject("$lte", movie.getEndYear()));
            yearConditions.add(basicDBObject);
        }
        if (yearConditions.size() > 0) {
            filter_dbobject.put("$and", yearConditions);
        }
        if (movie.getLanguage() != null) {
            filter_dbobject.put("language", Pattern.compile("^.*" + movie.getLanguage() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (movie.getGenreIds() != null) {
            BasicDBList basicDBList = new BasicDBList();
            for (Integer genreId : movie.getGenreIds()) {
                basicDBList.add(genreId);
            }
            filter_dbobject.put("genres.id", new BasicDBObject("$in", basicDBList));
        }
        if (movie.getRegion() != null) {
            filter_dbobject.put("region", Pattern.compile("^.*" + movie.getRegion() + ".*$", Pattern.CASE_INSENSITIVE));
        }

        //下面执行查询，设置limit,只要10条数据,排序(类mysql orderby) 再建一个BasicDBObject即可，－1表示倒序
        DBCursor cursor = movieDAO.selectMovie(filter_dbobject);

        MovieController.totalRow = cursor.count();
        if (movie.getPagerSize() != null) {
            cursor.limit(movie.getPagerSize());
        }
        int offset = 0;
        if (movie.getPageNumber() != null) {
            offset = (movie.getPageNumber() - 1) * movie.getPagerSize();
        }
        if (movie.getOffset() != null) {
            offset += movie.getOffset();
        }
        cursor.skip(offset);
        if (movie.getOrderField() != null) {
            // 根据排序规则排序，默认升序
            if (movie.getOrderDirection() != null) {
                cursor.sort(new BasicDBObject(movie.getOrderField(), "ASC".equalsIgnoreCase(movie.getOrderDirection()) ? 1 : -1));
            } else {
                cursor.sort(new BasicDBObject(movie.getOrderField(), 1));
            }
        }
        List<DBObject> dbObjects = cursor.toArray();
        return BeanUtil.copyToList(dbObjects, Movie.class);
    }
}
